import axios, {AxiosRequestConfig, Method} from 'axios';
import {Cookies} from 'react-cookie';


const cookie = new Cookies();

const request = axios.create({
    baseURL: 'http://10.93.220.249:3000',
    // baseURL: 'http://192.168.0.103:3000',
    timeout: 3000,
});

/**
 * 真实请求方法
 * @param parameters
 * @param method
 */
function doRequest<T>(parameters: IHttpClientRequestParameter<T>, method: Method): Promise<T> {
    return new Promise<T>((resolve, reject) => {
        const {url, tokenType, params, data} = parameters;
        const options: AxiosRequestConfig = {
            method: method,
            url: url,
            params: params === undefined ? {} : params,
            headers: {
                'Content-Type': 'application/json; charset=utf-8',
            },
            data: data === undefined ? {} : data,
        };
        try {
            handleToken(options, tokenType);
            request(options)
                .then((res: any) => {
                    resolve(res as T);
                })
                .catch((err: Error) => {
                    reject(err);
                });
        } catch (e) {
            // 统一抓异常，由调用者处理
            return Promise.reject(e);
        }
    });
}

/**
 * 处理请求携带的token
 * @param options
 * @param tokenType
 */
const handleToken = (options: AxiosRequestConfig, tokenType: string) => {
    if (tokenType !== '') {
        switch (tokenType) {
            case 'app_token':
                options.headers['Authorization'] = `Bearer ${cookie.get('app_access_token')}`;
                break;
            case 'tenant_token':
                options.headers['Authorization'] = `Bearer ${cookie.get('tenant_access_token')}`;
                break;
            case 'user_token':
                options.headers['Authorization'] = `Bearer ${cookie.get('user_access_token')}`;
                break;
            default:
                throw new Error('token 类型必须是 app_token, tenant_token, user_token 三种，如果不需要token，传空字符串即可');
        }
    }
};

interface IHttpClientRequestParameter<T> {
    url: string; // 请求路径，不加 baseUrl
    tokenType: string; // token 类型，只支持 app_token, tenant_token, user_token
    params?: T; // 查询参数
    data?: T; // 请求体参数
}

export interface IHttpClient {
    get<T>(parameters: IHttpClientRequestParameter<T>): Promise<T>;

    post<T>(parameters: IHttpClientRequestParameter<T>): Promise<T>;

    delete<T>(parameters: IHttpClientRequestParameter<T>): Promise<T>;
}

// TODO 优化统一请求方法
export class HttpClient implements IHttpClient {
    get<T>(parameters: IHttpClientRequestParameter<T>): Promise<T> {
        return doRequest(parameters, 'GET');
    }

    post<T>(parameters: IHttpClientRequestParameter<T>): Promise<T> {
        return doRequest(parameters, 'POST');
    }

    delete<T>(parameters: IHttpClientRequestParameter<T>): Promise<T> {
        return doRequest(parameters, 'DELETE');
    }
}

export const httpClient = new HttpClient();
